import os
import time
import re
from xml.dom.minidom import parseString

LOG_FILE = os.path.join('%s%slogs' % (os.path.dirname(os.path.abspath(__file__)), os.sep),
                        'update_host_info_%s.log' % time.strftime('%Y%m%d%H%M%S'))

from _log import FileLog
LOG = FileLog(LOG_FILE)

from _db_connection import DatabaseConnection
from _sart_connection import SartConnection


class Host(object):
    def __init__(self, ip, name, user, password):
        self.ip = ip
        self.name = name
        self.user = user
        self.password = password
        self.os = ''
        self.cpu = ''
        self.memory = ''
        self.harddisk = ''
        self.na_build = ''
        self.sart_build = ''


def _update_host_table():
    LOG._log('INFO: start _update_host_table')

    hosts = _get_host_list()
    for host in hosts:
        host_info = _get_host_info(host)
        _update_host_info(host)

    LOG._log('INFO: end _update_host_table')


def _get_host_list():
    """
    Get all host available with table 'host'
    """
    LOG._log('INFO: start _get_host_list')

    hosts = []
    ret = DB_CONN.execute_sql_statement('select host_ip, host_name, username, password from host_info')
    rows = ret.fetchall()
    for row in rows:
        host = Host(row[0], row[1], row[2], row[3])
        hosts.append(host)

    LOG._log('INFO: end _get_host_list')
    return hosts


def _get_host_info(host):
    """
    Get host's system information including:
        - operating system
        - CPU
        - memory
        - harddisk
        - NA/SART build number if applicable
    """
    LOG._log('INFO: start _get_host_info %s' % host.ip)

    #_get_host_system_info(host)
    _get_sart_info(host)

    LOG._log('INFO: end _get_host_info %s' % host.ip)


def _get_host_system_info(host):
    """
    Get host's system information including:
        - operating system
        - CPU
        - memory
        - harddisk
    """
    cmd = 'systeminfo /S %s /U %s\\%s /P %s' % (host.ip, host.name, host.user, host.password)
    ret = os.popen(cmd)
    info = ret.readlines()
    _parse_system_info(host, info)


def _parse_system_info(host, info):
    for line in info:
        ret = re.search('OS\s*NAME:\s*(.*)', line, re.I)
        if ret:
            os_type = ret.group(1)
            host.os = re.sub('Microsoft|\?|(\(.*?\))', '', os_type, re.I).strip()


def _get_sart_info(host):
    """
    Get host's system information including:
        - NA build number
        - SART build number
    """
    LOG._log('INFO: start _get_sart_info %s' % host.ip)

    versionInfoCommand = '<versionQuery/>'
    sart_connection = SartConnection(host.ip, LOG)
    output = sart_connection.execute_command(versionInfoCommand)

    if output:
        dom = parseString(output)
        versionInfoElements = dom.getElementsByTagName('versionInfo')

        for versionInfoElement in versionInfoElements:
            elementType = versionInfoElement.getAttribute('type')
            if elementType == 'na':
                host.na_build = versionInfoElement.getAttribute('buildVersion')
            if elementType == 'sa':
                host.sart_build = versionInfoElement.getAttribute('buildversion')
            #print host.ip, host.na_build, host.sart_build

    LOG._log('INFO: end _get_sart_info %s' % host.ip)


def _update_host_info(host):
    """
    Update host information to table 'host_info'
    """
    LOG._log('INFO: start _update_host_info %s' % host.ip)

    if host.na_build != '':
        sql_command = 'update host_info set na_build_id="%s", where host_ip="%s"' % (host.na_build, host.ip)
        DB_CONN.execute_sql_statement(sql_command)
    if host.sart_build != '':
        sql_command = 'update host_info set sart_build_id="%s", where host_ip="%s"' % (host.sart_build, host.ip)
        DB_CONN.execute_sql_statement(sql_command)

    LOG._log('INFO: end _update_host_info %s' % host.ip)



if __name__ == '__main__':
    DB_CONN = DatabaseConnection(LOG)
    try:
		_update_host_table()
    except Exception, e:
        LOG._log("ERROR: %s" % e)
        pass
    finally:
	    DB_CONN.close_database_connection()